Activi7工作流经典实战(附:常用流程流转代码片段)

您所在的位置:网站首页 activity 工作流程的部署 Activi7工作流经典实战(附:常用流程流转代码片段)

Activi7工作流经典实战(附:常用流程流转代码片段)

#Activi7工作流经典实战(附:常用流程流转代码片段)| 来源: 网络整理| 查看: 265

一、Activiti7介绍

Activiti正是目前使用最为广泛的开源工作流引擎。Activiti的官网地址是 https:// www.activiti.org 历经6.x和5.x两个大的版本。 在这里插入图片描述

1. Activiti工作流引擎

他可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN2.0进行定义。业务流程按照预先定义的流程执行,整个实现流程完全由activiti进行管理

获取流程引擎的两种方式:

ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml", "processEngineConfiguration"); ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();

默认方式

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService processEngine = processEngine.getRepositoryService();

注: 如果与springBoard整合的话,项目启动的时候会自动部署resources/processes目录下流程资源及自动获取流程引擎

2. 建模语言BPMN

整个BPMN是用一组符号来描述业务流程中发生的各种事件的。BPMN通过在这些符号事件之间连线来描述一个完整的业务流程。

在线设计地址: http://www.bpmnmodeler.com/SpringBoot集成activitimodeler实现在线绘制流程图

在这里插入图片描述

idea开发工具安装插件 Activiti BPMN visualizer(重启生效)

在这里插入图片描述

3. Activiti使用步骤 部署activiti: Activiti包含一堆Jar包,因此需要把业务系统和Activiti的环境集成 在一起进行部署。定义流程: 使用Activiti的建模工具定义业务流程.bpmn文件。部署流程定义: 使用Activiti提供的API把流程定义内容存储起来,在Acitivti执行过程汇总可以查询定义的内容。Activiti是通过数据库来存储业务流程的。启动流程实例: 流程实例也叫ProcessInstance。启动一个流程实例表示开始一次业务流程的运作。例如员工提交请假申请后,就可以开启一个流程实例,从而 推动后续的审批等操作。用户查询待办任务(task):因为现在系统的业务流程都交给了activiti管理,通过activiti就可以查询当前流程执行到哪个步骤了。当前用户需要办理哪些任务也就同样可以由activiti帮我们管理,开发人员不需要自己编写sql语句进行查询了。用户办理任务:用户查询到自己的待办任务后,就可以办理某个业务,如果这个业务办理完成还需要其他用户办理,就可以由activiti帮我们把工作流程往后面的 步骤推动。流程结束:当任务办理完成没有下一个任务节点后,这个流程实例就执行完成 了。 二、Activiti核心类

当拿到ProcessEngine之后,我们可以简单的看一下他的方法 这几个service就是activiti最为核心的几个服务实现类。围绕activiti的核心业务功能 大都通过这几个service来组成。

在这里插入图片描述

service名称service作用RepositoryServiceactiviti的资源管理类RuntimeServiceactiviti的流程运行管理类TaskServiceactiviti的任务管理类HistoryServiceactiviti的历史管理类ManagerServiceactiviti的引擎管理类

RepositoryService

是activiti的资源管理类,提供了管理和控制流程发布包和流程定义的操作。 使用工作流建模工具设计的业务流程图需要使用此service将流程定义文件的内容部署到计算机。 除了部署流程定义以外还可以:查询引擎中的发布包和流程定义。 暂停或激活发布包,对应全部和特定流程定义。 暂停意味着它们不能再执行任何操作了,激活是对应的反向操作。 获得多种资源,像是包含在发布包里的文件, 或引擎自动生成的流程图。

RuntimeService Activiti的流程运行管理类。可以从这个服务类中获取很多关于流程执行相关的信息

TaskService Activiti的任务管理类。可以从这个类中获取任务的信息。

HistoryService Activiti的历史管理类,可以查询历史信息,执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的 参与者, 完成任务的时间,每个流程实例的执行路径等等。 这个服务主要通过查询功能来获得这些数据。

ManagementService Activiti的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于 Activiti 系统的日常维护

三、流程部署

如果与springBoard整合的话,项目启动的时候会自动部署resources/processes目录下流程资源及自动获取流程引擎

1、流程部署的两种方式,手动部署: @Test public void deployProcess(){ Deployment deployment = repositoryService.createDeployment() .addClasspathResource("bpmn/incluProcess.bpmn20.xml") // 添加bpmn资源 //png资源命名是有规范的。Leave.[key].[png|jpg|gif|svg] 或者Leave.[png|jpg|gif|svg] .addClasspathResource("bpmn/incluProcess.png") // 添加png资源 .name("流程部署名称") .deploy(); // 4、输出部署信息 System.out.println("流程部署id:" + deployment.getId()); System.out.println("流程部署名称:" + deployment.getName()); } 2、手动压缩包方式部署: @Test public void deployProcessByZip() { // 定义zip输入流 InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/incluProcess.zip"); ZipInputStream zipInputStream = new ZipInputStream(inputStream); // 流程部署 Deployment deployment = repositoryService.createDeployment() .addZipInputStream(zipInputStream) .name("流程部署名称") .deploy(); System.out.println("流程部署id:" + deployment.getId()); System.out.println("流程部署名称:" + deployment.getName()); } 3、根据流程部署id获取流程部署资源: @Test public void queryBpmnFile() throws IOException { //流程定义key String processDefinitionKey = "incluProcess"; //得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .processDefinitionKey(processDefinitionKey) .latestVersion()//最新版本 .singleResult(); //.list(); //通过流程定义信息,得到部署ID String deploymentId = processDefinition.getDeploymentId(); //通过repositoryService的方法,实现读取图片信息和bpmn信息 //png图片的流 InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName()); //bpmn文件的流 InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName()); //构造OutputStream流 File file_png = new File("d:/incluProcess.png"); File file_bpmn = new File("d:/incluProcess.bpmn20.xml"); FileOutputStream bpmnOut = new FileOutputStream(file_bpmn); FileOutputStream pngOut = new FileOutputStream(file_png); //输入流,输出流的转换 IOUtils.copy(pngInput,pngOut); IOUtils.copy(bpmnInput,bpmnOut); //关闭流 pngOut.close(); bpmnOut.close(); pngInput.close(); bpmnInput.close(); } 4、根据流程部署id删除流程部署: @Test public void deleteDeployment() { //流程部署id String processDeploymentId = "f46f3734-e4bb-11ed-822f-9c5c8e74980c"; //删除流程定义,如果该流程定义已有流程实例启动则删除时出错 //repositoryService.deleteDeployment(processDeploymentId); //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程 repositoryService.deleteDeployment(processDeploymentId, true); } 四、流程定义与流程实例

流程定义 ProcessDefinition 和流程实例ProcessInstance是Activiti中非常重要的两个概念。他们的关系其实类似于JAVA中类和对象的概念。 流程定义ProcessDefinition是以BPMN文件定义的一个工作流程,是一组工作规范。例如我们之前定义的请假流程。 流程实例ProcessInstance则是指一个具体的业务流程。例如某个员工发起一次请假,就会实例化一个请假的流程实例,并且每个 不同的流程实例之间是互不影响的。

1、启动流程实例: /** * 启动流程实例(设置流程变量的值和添加businessKey) * 同一个流程定义key部署多个版本,默认使用最新版本 * 一个流程定义下有多个实例 */ @Test public void startProcess(){ //流程定义key String processDefinitionKey = "incluProcess"; //businessKey业务关键字 // 可以根据业务场景,设计成不同的数据格式,比如关键信息逗号拼接,甚至是json都可以,唯一需要注意的是这个字段的数据库长度设计是255 String businessKey = "{\"workerId\": 1,\"departmentId\": \"123\",\"roleId\": 2,\"other\": 3}"; //创建Global流程变量(启动流程时),在线程实例中传递的流程变量。这个流程变量可以在整个流程实例中使用 Map map = new HashMap(); map.put("assignee0","tom"); map.put("assignee1","jack"); //启动流程实例,并设置流程变量的值(把map传入)&&启动流程实例时,添加Businesskey,可以用这个businessKey来关联业务 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey,map); //输出 System.out.println("流程定义id=="+processInstance.getProcessDefinitionId());//流程定义key:版本号:流程部署ID ==> incluProcess:1:1b99a469-e425-11ed-a092-9c5c8e74980c System.out.println("流程实例名称="+processInstance.getName()); System.out.println("流程实例id:" + processInstance.getId());//56987f81-e429-11ed-8ad9-9c5c8e74980c System.out.println("当前活动Id:" + processInstance.getActivityId()); System.out.println("BusinessKey:" + processInstance.getBusinessKey()); } 2、流程定义

查询流程定义:

@Test public void queryProcessDefinition(){ //流程定义key String processDefinitionKey = "incluProcess"; ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); //查询出当前所有的流程定义 List definitionList = processDefinitionQuery.processDefinitionKey(processDefinitionKey) .orderByProcessDefinitionVersion() .desc()按照版本倒叙 .list(); //输出流程定义信息 for (ProcessDefinition processDefinition : definitionList) { System.out.println("流程部署ID ="+processDefinition.getDeploymentId());//1b598e26-e425-11ed-a092-9c5c8e74980c System.out.println("流程定义 id="+processDefinition.getId());//incluProcess:1:1b99a469-e425-11ed-a092-9c5c8e74980c System.out.println("流程定义 name="+processDefinition.getName());//出差申请-包含网关 System.out.println("流程定义 key="+processDefinition.getKey());//incluProcess System.out.println("流程定义 Version="+processDefinition.getVersion());//1 System.out.println(""); } }

流程定义的挂起与激活:

repositoryService.suspendProcessDefinitionById(processDefinitionId); repositoryService.activateProcessDefinitionById(processDefinitionId); 3、流程实例

查询流程实例:

@Test public void queryProcessInstance() { //流程定义key String processDefinitionKey = "incluProcess"; List list = runtimeService .createProcessInstanceQuery() .processDefinitionKey(processDefinitionKey) //.processInstanceId("9f50db66-e4a0-11ed-bd31-9c5c8e74980c") .list(); for (ProcessInstance processInstance : list) { System.out.println("所属流程定义id:"+ processInstance.getProcessDefinitionId());//incluProcess:1:1b99a469-e425-11ed-a092-9c5c8e74980c System.out.println("所属流程定义 Version="+processInstance.getProcessDefinitionVersion()); System.out.println("流程实例id:"+ processInstance.getProcessInstanceId());//56987f81-e429-11ed-8ad9-9c5c8e74980c System.out.println("是否执行完成:" + processInstance.isEnded());//false System.out.println("是否暂停:" + processInstance.isSuspended());//false System.out.println("当前活动标识:" + processInstance.getActivityId());//null System.out.println("业务关键字:"+processInstance.getBusinessKey());//null System.out.println("流程变量 Variables="+ JSON.toJSONString(processInstance.getProcessVariables())); System.out.println(""); } }

流程实例的挂起与激活:

runtimeService.suspendProcessInstanceById(processInstanceId); runtimeService.activateProcessInstanceById(processInstanceId); 4、查看历史信息: @Test public void findHistoryInfo(){ //获取 actinst表的查询对象 HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery(); //查询 actinst表,条件:根据 DefinitionId 查询,查询一种流程定义的所有历史信息 instanceQuery.processDefinitionId("incluProcess:1:9fe8bf00-e4d9-11ed-8e1f-9c5c8e74980c"); //查询 actinst表,条件:根据 InstanceId 查询,查询一个流程实例的所有历史信息 //instanceQuery.processInstanceId("a65107ee-e42e-11ed-b64e-9c5c8e74980c"); //增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序 instanceQuery.orderByHistoricActivityInstanceStartTime().asc(); //查询所有内容 List activityInstanceList = instanceQuery.list(); //输出 for (HistoricActivityInstance hi : activityInstanceList) { System.out.println("流程定义id:"+hi.getProcessDefinitionId()); System.out.println("流程实例id:"+hi.getProcessInstanceId()); System.out.println("ActivityType:"+hi.getActivityType()); System.out.println("ActivityId:"+hi.getActivityId()); System.out.println("ActivityName:"+hi.getActivityName()); System.out.println("执行人Assignee:"+hi.getAssignee()); System.out.println("TaskId:"+hi.getTaskId()); System.out.println(""); } } 五、流程变量

变量的作用域可以设置为Global和Local两种。

1. Global变量

这个是流程变量的默认作用域,表示是一个完整的流程实例。 Global变量中变量 名不能重复。如果设置了相同的变量名,后面设置的值会直接覆盖前面设置的变量值

通过启动流程时候设置变量 ProcessInstance processInstance =runtimeService.startProcessInstanceByKey(key, map); 通过当前流程实例设置变量 // 通过流程实例执行实例编号设置流程变量 runtimeService.setVariable(executionId, "evection", evection); // 一次设置多个值 runtimeService.setVariables(executionId, variables)

注: executionId必须是当前未完成的流程实例的执行ID。通常此ID设 置流程实例的ID。流程变量设计完成后,也可以通过 runtimeService.getVariable()获取流程变量

通过当前任务设置变量 //通过任务设置流程变量 taskService.setVariable(taskId, "evection", evection); //一次设置多个值 taskService.setVariables(taskId, variables)

注: 任务id必须是当前待办任务id,act_ru_task中存在。如果该任务已结束,会报错。也可以通过taskService.getVariable()获取流程变量

任务办理是设置变量 taskService.complete(task.getId(),map); 2. Local变量

Local变量的作用域只针对一个任务或一个执行实例的范围,没有流程实例大。 Local变量由于作用在不同的任务或不同的执行实例中,所以不同变量的作用域是 互不影响的,变量名可以相同。Local变量名也可以和Global变量名相同,不会有影响

通过当前流程实例设置变量 // 通过流程实例执行实例编号设置流程变量 runtimeService.setVariableLocal(executionId, "evection", evection); // 一次设置多个值 runtimeService.setVariableLocal(executionId, variables) 通过当前任务设置变量 // 通过任务设置流程变量 taskService.setVariableLocal(taskId, "evection", evection); // 一次设置多个值 taskService.setVariablesLocal(taskId, variables) 3. 使用流程变量

Activiti中可以使用UEL表达式来使用这些流程变量。UEL表达式可以直接获取一 个变量的值,可以计算一个Boolean结果的表达式,还可以直接使用某些对象的属性。

例如: 设置数组大于等于3: ${num SysUser user = getSysUser(); String username = user.getLoginName(); //构建任务查询条件 TaskQuery condition = taskService.createTaskQuery().taskAssignee(username); if (StringUtils.isNotEmpty(param.getTaskName())) { condition.taskName(param.getTaskName()); } if (StringUtils.isNotEmpty(param.getProcessName())) { condition.processDefinitionName(param.getProcessName()); } // 过滤掉流程挂起的待办任务 int total = condition.active().orderByTaskCreateTime().desc().list().size(); int start = (param.getPageNum()-1) * param.getPageSize(); //根据构建的任务条件分页查询任务列表 List taskList = condition.active().orderByTaskCreateTime().desc().listPage(start, param.getPageSize()); List tasks = new ArrayList(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); taskList.stream().forEach(a->{ //根据任务列表中的所属流程实例ID获取流程实例对象 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(a.getProcessInstanceId()).singleResult(); TaskInfo info = new TaskInfo(); info.setAssignee(a.getAssignee());//任务执行人(办理人) info.setCreateTime(sdf.format(a.getCreateTime()));//任务创建时间 info.setTaskName(a.getName());//任务名称 info.setProcessInstanceId(a.getProcessInstanceId());//流程实例ID info.setTaskId(a.getId());//任务ID info.setExecutionId(a.getExecutionId());//执行实例编号ID String formKey = formService.getTaskFormData(a.getId()).getFormKey(); info.setFormKey(formKey);//流程自定义表单Key //从流程实例中获取流程定义名称、流程开始人、businessKey、流程启动事件 info.setProcessName(process.getProcessDefinitionName());//流程定义名称 info.setStarter(process.getStartUserId());//任务发起人 info.setBusinessKey(process.getBusinessKey());//businessKey info.setStartTime(sdf.format(process.getStartTime()));//流程启动事件 tasks.add(info); }); TableDataInfo rspData = new TableDataInfo(); rspData.setCode(0); rspData.setRows(tasks); rspData.setTotal(total); return rspData; }

流程审批

@GetMapping("/deptleadercheck") public String deptleadercheck(String taskid, ModelMap mmap) { //根据taskId获取任务对象和流程实例 Task t = taskService.createTaskQuery().taskId(taskid).singleResult(); String processId = t.getProcessInstanceId(); ProcessInstance p = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult(); if (p != null) { //根据流程实例中的businessKey获取业务对象 Leaveapply apply = leaveapplyService.selectLeaveapplyById(Long.parseLong(p.getBusinessKey())); mmap.put("apply", apply); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); mmap.put("startTime", sdf.format(apply.getStartTime())); mmap.put("endTime", sdf.format(apply.getEndTime())); mmap.put("taskid", taskid); mmap.put("userlist", userService.selectUserList(new SysUser())); } return prefix + "/deptleadercheck"; }

办理任务

@RequestMapping(value = "/completeTask/{taskId}", method = RequestMethod.POST) @ResponseBody public AjaxResult completeTask(@PathVariable("taskId") String taskId, @RequestBody(required=false) Map variables) { SysUser user = getSysUser(); String username = user.getLoginName(); //设置办理任务的执行人 taskService.setAssignee(taskId, username); // 查出流程实例id String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId(); if (variables == null) { taskService.complete(taskId); } else { // 添加审批意见 if (variables.get("comment") != null) { //根据流程实例ID和任务ID添加审批意见 taskService.addComment(taskId, processInstanceId, (String) variables.get("comment")); variables.remove("comment"); } taskService.complete(taskId, variables); } return AjaxResult.success(); }

驳回或跳转到指定节点

@GetMapping(value = "/jump/{taskId}/{sid}") @ResponseBody public AjaxResult jump(@PathVariable String taskId, @PathVariable String sid) { //根据任务id获取任务实例,通过流程定义ID获取bpmn模型 Task t = taskService.createTaskQuery().taskId(taskId).singleResult(); String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(t.getProcessInstanceId()).singleResult().getProcessDefinitionId(); BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); //根据执行实例编号executionId获取流程图(FlowNode)中当前活动的id(activityId);寻找流程实例当前任务的activeId Execution execution = runtimeService.createExecutionQuery().executionId(t.getExecutionId()).singleResult(); String activityId = execution.getActivityId(); FlowNode currentNode = (FlowNode)bpmnModel.getMainProcess().getFlowElement(activityId); FlowNode targetNode = (FlowNode)bpmnModel.getMainProcess().getFlowElement(sid); // 创建连接线 List newSequenceFlowList = new ArrayList(); SequenceFlow newSequenceFlow = new SequenceFlow(); newSequenceFlow.setId("newFlow"); newSequenceFlow.setSourceFlowElement(currentNode); newSequenceFlow.setTargetFlowElement(targetNode); newSequenceFlowList.add(newSequenceFlow); // 备份原有方向 List dataflows = currentNode.getOutgoingFlows(); List oriSequenceFlows = new ArrayList(); oriSequenceFlows.addAll(dataflows); // 清空原有方向 currentNode.getOutgoingFlows().clear(); // 设置新方向 currentNode.setOutgoingFlows(newSequenceFlowList); //添加流程说明并完成当前任务 taskService.addComment(taskId, t.getProcessInstanceId(), "comment", "跳转节点"); taskService.complete(taskId); // 恢复原有方向 currentNode.setOutgoingFlows(oriSequenceFlows); return AjaxResult.success(); }

撤销:强制结束一个流程

@GetMapping(value = "/forceEnd/{taskId}") @ResponseBody public AjaxResult forceEnd(@PathVariable String taskId) { Task t = taskService.createTaskQuery().taskId(taskId).singleResult(); String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(t.getProcessInstanceId()).singleResult().getProcessDefinitionId(); BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); // 寻找流程实例当前任务的activeId Execution execution = runtimeService.createExecutionQuery().executionId(t.getExecutionId()).singleResult(); String activityId = execution.getActivityId(); FlowNode currentNode = (FlowNode)bpmnModel.getMainProcess().getFlowElement(activityId); // 创建结束节点和连接线 EndEvent end = new EndEvent(); end.setName("强制结束"); end.setId("forceEnd"); List newSequenceFlowList = new ArrayList(); SequenceFlow newSequenceFlow = new SequenceFlow(); newSequenceFlow.setId("newFlow"); newSequenceFlow.setSourceFlowElement(currentNode); newSequenceFlow.setTargetFlowElement(end); newSequenceFlowList.add(newSequenceFlow); // 备份原有方向 List dataflows = currentNode.getOutgoingFlows(); List oriSequenceFlows = new ArrayList(); oriSequenceFlows.addAll(dataflows); // 清空原有方向 currentNode.getOutgoingFlows().clear(); // 设置新方向并添加说明完成任务后恢复原有方向 currentNode.setOutgoingFlows(newSequenceFlowList); // 完成当前任务 taskService.addComment(taskId, t.getProcessInstanceId(), "comment", "撤销流程"); taskService.complete(taskId); // 恢复原有方向 currentNode.setOutgoingFlows(oriSequenceFlows); return AjaxResult.success(); } 2、流程定义和流程实例可视化管理

查询已部署工作流列表

@RequestMapping(value = "/getprocesslists", method = RequestMethod.POST) @ResponseBody public TableDataInfo getlist(@RequestParam(required = false) String key, @RequestParam(required = false) String name, @RequestParam(required = false) Boolean latest, Integer pageSize, Integer pageNum) { //构建流程定义条件查询实例 ProcessDefinitionQuery queryCondition = repositoryService.createProcessDefinitionQuery(); if (StringUtils.isNotEmpty(key)) { queryCondition.processDefinitionKey(key); } if (StringUtils.isNotEmpty(name)) { queryCondition.processDefinitionName(name); } if (latest) { queryCondition.latestVersion(); } int total = queryCondition.list().size(); int start = (pageNum - 1) * pageSize; //分页查询流程定义 List pageList = queryCondition.orderByDeploymentId().desc().listPage(start, pageSize); List mylist = new ArrayList(); for (int i = 0; i //根据流程部署ID删除部署的工作流 repositoryService.deleteDeployment(deploymentId, true); return AjaxResult.success(); }

根据流程定义ID查看工作流图片

@RequestMapping(value = "/showresource", method = RequestMethod.GET) public void showresource(@RequestParam("pdid") String pdid, HttpServletResponse response) throws Exception { //根据流程定义ID查询工作流图片 BpmnModel bpmnModel = repositoryService.getBpmnModel(pdid); //@Resource //ProcessEngineConfiguration configuration; ProcessDiagramGenerator diagramGenerator = configuration.getProcessDiagramGenerator(); InputStream is = diagramGenerator.generateDiagram(bpmnModel, "png", "宋体", "宋体", "宋体", configuration.getClassLoader(), 1.0); ServletOutputStream output = response.getOutputStream(); IOUtils.copy(is, output); }

根据流程定义ID定时唤醒一个流程定义

@RequestMapping(value = "/activateProcessDefinition", method = RequestMethod.GET) @ResponseBody public AjaxResult activateProcessDefinition(@RequestParam("pdid") String pdid, @RequestParam("flag") Boolean flag, @RequestParam(value="date") String date) throws Exception { //激活一个流程定义 if (StringUtils.isNotEmpty(date)) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); repositoryService.activateProcessDefinitionById(pdid, flag, sdf.parse(date)); } else { repositoryService.activateProcessDefinitionById(pdid, flag, null); } return AjaxResult.success(); }

根据流程定义ID定时挂起一个流程定义

@RequestMapping(value = "/suspendProcessDefinition", method = RequestMethod.GET) @ResponseBody public AjaxResult suspendProcessDefinition(@RequestParam("pdid") String pdid, @RequestParam("flag") Boolean flag, @RequestParam(value="date") String date) throws Exception { //定时挂起一个流程定义 if (StringUtils.isNotEmpty(date)) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); repositoryService.suspendProcessDefinitionById(pdid, flag, sdf.parse(date)); } else { repositoryService.suspendProcessDefinitionById(pdid, flag, null); } return AjaxResult.success(); }

查询所有正在运行的流程实例列表

@RequestMapping(value = "/listProcess", method = RequestMethod.POST) @ResponseBody public TableDataInfo getlist(@RequestParam(required = false) String bussinesskey, @RequestParam(required = false) String name, Integer pageSize, Integer pageNum) { int start = (pageNum - 1) * pageSize; //构建流程实例条件查询实例 ProcessInstanceQuery condition = runtimeService.createProcessInstanceQuery(); if (StringUtils.isNotEmpty(bussinesskey)) { condition.processInstanceBusinessKey(bussinesskey); } if (StringUtils.isNotEmpty(name)) { condition.processDefinitionName(name); } int total = condition.orderByProcessDefinitionId().desc().list().size(); //分页查询流程实例 List processList = condition.orderByProcessDefinitionId().desc().listPage(start, pageSize); List flows = new ArrayList(); processList.stream().forEach(p -> { FlowInfo info = new FlowInfo(); info.setProcessInstanceId(p.getProcessInstanceId()); info.setBusinessKey(p.getBusinessKey()); info.setName(p.getProcessDefinitionName()); info.setStartTime(p.getStartTime()); info.setStartUserId(p.getStartUserId()); info.setSuspended(p.isSuspended()); info.setEnded(p.isEnded()); // 查看当前活动任务 List tasks = taskService.createTaskQuery().processInstanceId(p.getProcessInstanceId()).list(); if (tasks.size() > 0) { String taskName = ""; String assignee = ""; for (Task t : tasks) { taskName += t.getName() + ","; assignee += t.getAssignee() + ","; } taskName = taskName.substring(0, taskName.length() -1); assignee = assignee.substring(0, assignee.length() -1); info.setCurrentTask(taskName); info.setAssignee(assignee); } flows.add(info); }); TableDataInfo rspData = new TableDataInfo(); rspData.setCode(0); rspData.setRows(flows); rspData.setTotal(total); return rspData; }

根据流程实例ID流程实例的挂起

@RequestMapping(value = "/suspend/{processInstanceId}", method = RequestMethod.GET) @ResponseBody public AjaxResult suspend(@PathVariable String processInstanceId) { //根据流程实例ID挂起一个流程实例 runtimeService.suspendProcessInstanceById(processInstanceId); return AjaxResult.success(); }

根据流程实例ID流程实例的唤醒

@RequestMapping(value = "/run/{processInstanceId}", method = RequestMethod.GET) @ResponseBody public AjaxResult rerun(@PathVariable String processInstanceId) { //根据流程实例ID唤醒一个流程实例 runtimeService.activateProcessInstanceById(processInstanceId); return AjaxResult.success(); }

根据流程实例id生成流程追踪图

public void generateFlowChart(String processInstanceId, OutputStream outputStream) { try { if (StringUtils.isEmpty(processInstanceId)) { logger.error("processInstanceId is null"); return; } // 获取历史流程实例 HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId) .singleResult(); // 获取流程中已经执行的节点 List historicActivityInstances = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId) .orderByHistoricActivityInstanceStartTime().asc().list(); // 高亮节点-高亮已经执行流程节点ID集合 List highLightedActivitiIds = new ArrayList(); for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { highLightedActivitiIds.add(historicActivityInstance.getActivityId()); } ProcessDiagramGenerator processDiagramGenerator = processEngineConfiguration.getProcessDiagramGenerator(); BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId()); // 高亮流程线-高亮流程已发生流转的线id集合 List highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances); // 生成流程追踪图-使用默认配置获得流程图表生成器,并生成追踪图片字符流 InputStream imageStream = processDiagramGenerator .generateDiagram(bpmnModel, "png", highLightedActivitiIds, highLightedFlowIds, "宋体", "微软雅黑", "黑体", null, 2.0); // 输出图片内容 byte[] b = new byte[1024]; int len; while ((len = imageStream.read(b, 0, 1024)) != -1) { outputStream.write(b, 0, len); } } catch (Exception e) { logger.error("processInstanceId" + processInstanceId + "生成流程图失败,原因:" + e.getMessage(), e); } } /** * 获取已经流转的线 * * @param bpmnModel 流程图模板 * @param historicActivityInstances 历史实例 */ private List getHighLightedFlows(BpmnModel bpmnModel, List historicActivityInstances) { // 高亮流程已发生流转的线id集合 List highLightedFlowIds = new ArrayList(); // 已完成的活动节点 List historicActivityNodes = new ArrayList(); for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true); historicActivityNodes.add(flowNode); } FlowNode currentFlowNode; FlowNode targetFlowNode; // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的 for (HistoricActivityInstance currentActivityInstance : historicActivityInstances) { // 获得当前活动对应的节点信息及outgoingFlows信息 currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true); List sequenceFlows = currentFlowNode.getOutgoingFlows(); // 通过outgoingFlows能够在历史活动中找到且目标节点和当前节点执行顺序相邻 for (SequenceFlow sequenceFlow : sequenceFlows) { targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true); if (historicActivityNodes.contains(targetFlowNode)) { int target = historicActivityNodes.indexOf(targetFlowNode); int current = historicActivityNodes.indexOf(currentFlowNode); if (target - current == 1) { //获取已经流转的线ID highLightedFlowIds.add(sequenceFlow.getId()); } } } } return highLightedFlowIds; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3